package mysql

import (
	"context"
	"go.uber.org/zap"
	"kf/config"
	"runtime/debug"
	"time"

	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
)

// 在上一篇文章写过https://blog.csdn.net/bei_FengBoby/article/details/124736603? 查询，直接拿过用
func ConnectMysql(config *config.Conf, log *zap.Logger) (*gorm.DB, func(), error) {
	//启用打印日志
	//newLogger := logger.New(
	//	//log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer
	//	log,
	//	logger.Config{
	//		SlowThreshold: time.Second, // 慢 SQL 阈值
	//		LogLevel:      logger.Info, // Log level: Silent、Error、Warn、Info
	//		Colorful:      false,       // 禁用彩色打印
	//	},
	//)
	newLogger := &ZapGormLogger{zapLogger: log}
	//换成自己的
	dsn := config.DB.UserName + ":" + config.DB.Password + "@tcp(" + config.DB.Host + ":" + config.DB.Port + ")/" +
		config.DB.DbName + "?charset=utf8mb4&parseTime=True&loc=Local"
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
		Logger: newLogger.LogMode(logger.Info),
	})
	//if err != nil {
	//	fmt.Println("---------------数据库连接失败-------------------")
	//	return
	//}
	if err != nil {
		log.Error("数据库连接失败")
		return nil, nil, err
	}

	return db, func() {
		sqlDB, err := db.DB()
		if err == nil {
			_ = sqlDB.Close()
		}
	}, nil
}

// ZapGormLogger 是一个实现了 gorm.Logger 接口的结构体
type ZapGormLogger struct {
	zapLogger *zap.Logger
}

// LogMode 实现了 gorm.Logger 接口的 LogMode 方法
// 这里可以返回自身，因为ZapGormLogger 已经是一个 LogMode
func (l *ZapGormLogger) LogMode(level logger.LogLevel) logger.Interface {
	// 实际上，这里不需要根据level改变行为，因为ZapGormLogger总是使用相同的zapLogger
	// 但如果你想要根据日志级别过滤日志，你可以在这里实现它
	return l
}

// Info 实现了 gorm.Logger 接口的 Info 方法
func (l *ZapGormLogger) Info(ctx context.Context, msg string, data ...interface{}) {
	l.zapLogger.Info(msg, zap.Any("data", data))
}

// Warn 实现了 gorm.Logger 接口的 Warn 方法
func (l *ZapGormLogger) Warn(ctx context.Context, msg string, data ...interface{}) {
	l.zapLogger.Warn(msg, zap.Any("data", data))
}

// Error 实现了 gorm.Logger 接口的 Error 方法
func (l *ZapGormLogger) Error(ctx context.Context, msg string, data ...interface{}) {
	l.zapLogger.Error(msg, zap.Any("data", data))
}

// Trace 实现了 gorm.Logger 接口的 Trace 方法（如果需要的话）
// GORM v1 可能没有这个方法，但在 GORM v2 中是存在的
func (l *ZapGormLogger) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) {
	if err != nil {
		debug.Stack()
		l.zapLogger.Error("trace error", zap.Error(err))
		return
	}

	sql, rows := fc()
	duration := time.Since(begin)
	l.zapLogger.Info("trace", zap.String("sql", sql), zap.Int64("rows", rows), zap.Duration("duration", duration))
}
